package com.als.healthymananger.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JWTUtil {
    @Value("${jwt.expired-time}")
    private long expriedTime;

    @Value("${jwt.secret}")
    private String secret = "healthy-mananger-aion";

    private final String CLAIM_KEY_ACCOUNT = "sub";
    private final String CLAIM_KEY_CREATED = "created";
    private final String CLAIM_KEY_TYPE = "userType";

    /**
     * 生成token
     * @param account 账号
     * @param userType 用户类型 ：用户、管理员
     * @return token字符串
     */
    public String creteToken(String account, String userType){
        // 荷载
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(CLAIM_KEY_ACCOUNT, account);
        claims.put(CLAIM_KEY_TYPE, userType);
        claims.put(CLAIM_KEY_CREATED, new Date());

        return generateJwt(claims);
    }

    private String generateJwt(Map<String, Object> claim) {
        //指定签名的时候使用的签名算法，也就是header那部分，jjwt已经将这部分内容封装好了。
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成token
        return Jwts.builder()
                .setClaims(claim)
                .setExpiration(new Date(System.currentTimeMillis() + expriedTime * 1000))  // 设置过期时间
                .signWith(signatureAlgorithm, secret)   // 设置签名算法和签名使用的秘钥
                .compact();
    }

    /**
     * 通过token获取到账号
     * @param token
     * @return
     */
    public String getAccountByToken(String token) {
        return getClaim("token", "sub");
    }

    /**
     * 根据荷载名从token中获取荷载
     * @param token
     * @param claimName
     * @return
     */
    public String getClaim(String token, String claimName) {
        Claims claims = getClaims(token);
        String claim = claims.get(claimName, String.class);
        return claim;
    }

    /**
     * 判断token是否过期
     * 如果token过期，得到的claims是null
     * @param token
     * @return
     */
    public boolean isExpired(String token) {
        Claims claims = getClaims(token);
//        Date expiration = claims.getExpiration();
//
//        // 过期时间在当前时间之前为为没有过期
//        return expiration.before(new Date());
        return claims == null ? true: false;
    }

    /**
     * 刷新token
     * @param token
     * @return
     */
    public String refreshToken(String token) {
        Claims claims = getClaims(token);
        claims.setExpiration(new Date(System.currentTimeMillis() + expriedTime));
        return generateJwt(claims);
    }

    /**
     * 从token中获取荷载
     * @param token
     * @return
     */
    private Claims getClaims(String token) {
        Claims claims;
        try{
            claims = Jwts.parser()
                    .setSigningKey(secret)  // 生成token时使用的秘钥
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e){
            claims = null;
        }
        return claims;
    }

}
